package org.adorsys.aderp.aderplogin.client.hessian;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.adorsys.aderp.aderplogin.client.basic.ClientBasicAuthenticator;
import org.adorsys.aderp.aderplogin.client.common.Oauth2User;
import org.adorsys.aderp.aderplogin.client.common.Oauth2UserCache;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

/**
 * Extends the preauthentication filter and returns as principal the user
 * loaded from the oauth token out of the request and as credential the
 * actual authentication from the client.
 * 
 * @author francis
 *
 */
public class HessianPreAuthenticatedProcessingFilter extends
		AbstractPreAuthenticatedProcessingFilter2 {

    private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();

    private Oauth2UserCache oauth2UserCache;
    
    private ClientBasicAuthenticator clientBasicAuthenticator;
    
	@Override
	protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {

		Oauth2User oauth2User = oauth2UserCache.retrieveAndStoreTokenFilter(request);
		if(oauth2User==null)
			throw new BadCredentialsException("Missing access token. Musst be sent with with the header parameter 'token'");

		return oauth2User;
	}

	@Override
	protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
		return clientBasicAuthenticator.authenticate(request);
	}

	@Override
	public void afterPropertiesSet() {
		super.afterPropertiesSet();		
		if(oauth2UserCache==null) throw new IllegalStateException("oauth2UserCache must be set");
		if(clientBasicAuthenticator==null) throw new IllegalStateException("clientBasicAuthenticator must be set");
	}

	@Override
	protected boolean requiresAuthentication(HttpServletRequest request) {
		return true;
	}

	@Override
	protected void unsuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, AuthenticationException failed) {
		super.unsuccessfulAuthentication(request, response, failed);
		try {
			failureHandler.onAuthenticationFailure(request, response, failed);
		} catch(Exception e){
			throw new IllegalStateException(e);
		}
	}

	public void setOauth2UserCache(Oauth2UserCache oauth2UserCache) {
		this.oauth2UserCache = oauth2UserCache;
	}

	public void setClientBasicAuthenticator(
			ClientBasicAuthenticator clientBasicAuthenticator) {
		this.clientBasicAuthenticator = clientBasicAuthenticator;
	}
	
	
	
}
